/****************************************************************************
 *
 *   Copyright (c) 2025 H743 Flight Control Project. All rights reserved.
 *   Adapted from PX4 Autopilot Project
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

/**
 * @file px4_sem.h
 * 
 * PX4 Semaphore Wrapper for FreeRTOS
 * 
 * This file provides a POSIX-like semaphore API wrapper around FreeRTOS
 * counting semaphores, maintaining compatibility with PX4's semaphore interface.
 */

#ifndef __PX4_PLATFORM_COMMON_PX4_SEM_H
#define __PX4_PLATFORM_COMMON_PX4_SEM_H

#include "px4_platform_common/defines.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief PX4 semaphore type
 * 
 * Wraps FreeRTOS SemaphoreHandle_t to provide POSIX-like interface
 */
typedef struct {
    SemaphoreHandle_t sem;  /**< FreeRTOS semaphore handle */
} px4_sem_t;

/**
 * @brief Semaphore protocol types (for compatibility with POSIX)
 */
#define SEM_PRIO_NONE       0  /**< No priority inheritance */
#define SEM_PRIO_INHERIT    1  /**< Priority inheritance */
#define SEM_PRIO_PROTECT    2  /**< Priority ceiling */

/**
 * @brief Initialize a semaphore
 * 
 * @param sem Pointer to semaphore structure
 * @param pshared Shared flag (ignored in FreeRTOS)
 * @param value Initial semaphore count
 * @return 0 on success, -1 on error
 */
int px4_sem_init(px4_sem_t *sem, int pshared, unsigned int value);

/**
 * @brief Destroy a semaphore
 * 
 * @param sem Pointer to semaphore structure
 * @return 0 on success, -1 on error
 */
int px4_sem_destroy(px4_sem_t *sem);

/**
 * @brief Wait on a semaphore (blocking)
 * 
 * @param sem Pointer to semaphore structure
 * @return 0 on success, -1 on error
 */
int px4_sem_wait(px4_sem_t *sem);

/**
 * @brief Try to wait on a semaphore (non-blocking)
 * 
 * @param sem Pointer to semaphore structure
 * @return 0 on success, -1 if semaphore not available
 */
int px4_sem_trywait(px4_sem_t *sem);

/**
 * @brief Wait on a semaphore with timeout
 * 
 * @param sem Pointer to semaphore structure
 * @param timeout_ms Timeout in milliseconds
 * @return 0 on success, -1 on timeout or error
 */
int px4_sem_timedwait(px4_sem_t *sem, uint32_t timeout_ms);

/**
 * @brief Post (signal) a semaphore
 * 
 * @param sem Pointer to semaphore structure
 * @return 0 on success, -1 on error
 */
int px4_sem_post(px4_sem_t *sem);

/**
 * @brief Get semaphore value
 * 
 * @param sem Pointer to semaphore structure
 * @param sval Pointer to store current semaphore count
 * @return 0 on success, -1 on error
 */
int px4_sem_getvalue(px4_sem_t *sem, int *sval);

/**
 * @brief Set semaphore protocol (for compatibility, may not be fully supported)
 * 
 * @param sem Pointer to semaphore structure
 * @param protocol Protocol type (SEM_PRIO_NONE, SEM_PRIO_INHERIT, SEM_PRIO_PROTECT)
 * @return 0 on success, -1 on error
 */
int px4_sem_setprotocol(px4_sem_t *sem, int protocol);

#ifdef __cplusplus
}
#endif

#endif /* __PX4_PLATFORM_COMMON_PX4_SEM_H */

